package storageManager;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Collections;

public class SystemCatologReport extends FileClass{
	public SystemCatologReport(String input) throws IOException{
		this.raf = new RandomAccessFile(input, "rw");
		if(size()==0){
			createAPage();
		}
	}
	public void createAPage() throws IOException{
		int pageNumber = this.numberOfPages();
		int offset = (pageNumber)*512;
		raf.seek(offset);
		raf.write(0);
		raf.seek(offset+256);
		raf.write(0);
	}
	public int isInFile(String s) throws IOException{
		byte[] temp = new byte[256];
		int pageNumber = numberOfPages();
		for(int i=0; i<pageNumber*2; i++){
			int offset = i*256;
			raf.seek(offset);
			raf.read(temp);
			TableRecord record = byteToRecord(temp);
			if(record.getStatus()==1 && s.equalsIgnoreCase(record.getTableName())){
				return i;
			}
		}
		return -1;
	}
	public ArrayList<Integer> firstAvailablePlace() throws IOException{
		ArrayList<Integer> result = new ArrayList<Integer>();
		int pageNumber = numberOfPages();
		for(int i=0; i<pageNumber*2; i++){
			int offset = i*256;
			raf.seek(offset);
			boolean status = raf.readBoolean();
			if(!status){
				result.add(i/2);
				result.add(i%2);
				return result;
			}
		}
		result.add(-1);
		return result;
	}
	public byte[] recordToByte(TableRecord record){
		byte[] recordInByte = new byte[256];
		recordInByte[0] = (byte) record.getStatus();
		System.arraycopy(Tools.stringToByte(record.getTableName(),27), 0, recordInByte, 1, record.getTableName().length());
		recordInByte[28] = (byte) record.getNumberOfFields();
		recordInByte[29] = (byte) record.getNumberOfTotalIndexRecord();
		recordInByte[30] = (byte) record.getSizeOfAnIndexRecord();
		recordInByte[31] = (byte) record.getNumberOfTotalDataRecord();
		recordInByte[32] = (byte) record.getSizeOfADataRecord();
		for(int i=0; i<record.getNumberOfFields(); i++){
			String temp = record.getFieldNames().get(i);
			System.arraycopy(Tools.stringToByte(temp,16), 0, recordInByte, 35+17*i, temp.length());
			recordInByte[51+17*i] = record.getFieldSizes().get(i).byteValue();
		}
		return recordInByte;
	}
	public void addTable(TableRecord record) throws IOException{
		ArrayList<Integer> availablePlace = firstAvailablePlace();
		int pageNumber = availablePlace.get(0);
		if(pageNumber>=0){
			int recordNumber = availablePlace.get(1);
			int offset = pageNumber*512+recordNumber*256;
			raf.seek(offset);
			raf.write(recordToByte(record));
		}else{
			createAPage();
			addTable(record);
		}
	}
	public void deleteATable(int page,String s) throws IOException{//index ve data dosyas� silmeyi eklemeyi unutma
		byte[] zeros = new byte[256];
		for(int i=0; i<2; i++){
			int offset = page*512+i*256;
			raf.seek(offset);
			raf.read(zeros);
			TableRecord record = byteToRecord(zeros);
			if(record.getStatus()==1 && s.equalsIgnoreCase(record.getTableName())){
				record.setStatus(0);
				raf.seek(offset);
				raf.write(recordToByte(record));
				File index = new File(s+"in.txt");
				File data = new File(s+"dat.txt");
				index.delete();
				data.delete();
			}
		}
	}
	public ArrayList<String> listOfAllTables() throws IOException{
		ArrayList<String> result = new ArrayList<String>();
		int size = (int) size();
		
		for(int i=0; i<numberOfPages()*2;i++){
			byte[] temp = new byte[256];
			int offset=256*i;
			raf.seek(offset);
			raf.read(temp);
			TableRecord record = byteToRecord(temp);
			if(record.getStatus()==1){
				result.add(record.getTableName());
			}
		}
		Collections.sort(result);
		return result;
	}
	public TableRecord findTheRecord(String tableName) throws IOException{
		int place = isInFile(tableName);
		if(place>=0){
			byte[] temp = new byte[256];
			raf.seek(place*256);
			raf.read(temp);
			return byteToRecord(temp);
		}else{
			return null;
		}
	}
	@Override
	public TableRecord byteToRecord(byte[] bytes) {
		TableRecord record = new TableRecord();
		record.setStatus(bytes[0]);
		record.setTableName(Tools.byteToString(bytes, 1, 27));
		record.setNumberOfFields(bytes[28]);
		record.setNumberOfTotalIndexRecord(bytes[29]);
		record.setSizeOfAnIndexRecord(bytes[30]);
		record.setNumberOfTotalDataRecord(bytes[31]);
		record.setSizeOfADataRecord(bytes[32]);
//		record.setFirstAvPageForDataRecord(bytes[33]);
//		record.setKeyValueIsNumeric(bytes[33]);
//		record.setFirstAvRecordForDataRecord(bytes[34]);
		ArrayList<String> names = new ArrayList<String>();
		ArrayList<Integer> sizes = new ArrayList<Integer>();
		for(int i=0; i<record.getNumberOfFields(); i++){
			names.add(Tools.byteToString(bytes, 35+17*i, 16));
			sizes.add((int)Tools.byteToString(bytes, 51+17*i, 1).charAt(0));
		}
		record.setFieldNames(names);
		record.setFieldSizes(sizes);
		return record;
	}
	@Override
	public Page byteToPage(int pageNumber) throws IOException {
		// TODO Auto-generated method stub
		return null;
	}
}
